package com.spark.market.service.manager;

import com.spark.market.api.dto.UserInfo;
import com.spark.market.common.constants.LogFileName;
import com.spark.market.common.constants.RedisCache;
import com.spark.market.common.exception.BusinessException;
import com.spark.market.common.exception.EmBusinessError;
import com.spark.market.common.utils.AssertUtils;
import com.spark.market.common.utils.LoggerUtils;
import com.spark.market.common.utils.RedisUtil;
import com.spark.market.common.validator.ValidationResult;
import com.spark.market.common.validator.ValidatorImpl;
import com.spark.market.dal.entity.UserInfoDo;
import com.spark.market.dal.entity.UserPasswordDo;
import com.spark.market.dal.model.UserModel;
import com.spark.market.dal.repository.UserPasswordRepository;
import com.spark.market.dal.repository.UserRepository;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Component
public class UserManager {
    Logger LOGGER = LoggerUtils.Logger(LogFileName.MARKET_LOG);

    @Resource
    private UserRepository userRepository;
    @Resource
    private UserPasswordRepository userPasswordRepository;
    @Resource
    private ValidatorImpl validator;

    @Resource
    private RedisUtil redis;

    public UserInfo queryUserById(Integer id) {
        AssertUtils.isNotNull(id, "userid is null");
        //查询用户信息
        UserInfoDo userInfoDo = userRepository.selectUserById(id);
        if (userInfoDo == null) return null;
        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(userInfoDo, userInfo);
        return userInfo;
    }

    public void createOptAndSave(String telephone) {
        AssertUtils.isNotNull(telephone, "telephone is null");
        //按照一定规则生成opt验证码
        Random random = new Random();
        int randomInt = random.nextInt(99999);
        randomInt += 10000;
        String optCode = String.valueOf(randomInt);
        //将opt验证码同手机号关联-Http Session
        redis.set(RedisCache.USER_REDIS_TELEPHONE_OPT + ":" + telephone, optCode);
        redis.expire(RedisCache.USER_REDIS_TELEPHONE_OPT + ":" + telephone,1, TimeUnit.HOURS);
        //将opt验证码通过短信构造发送给用户，省略
        LOGGER.info("用户验证码为：{}",optCode);
    }

    public void verify(String telephone,String optCode){
        AssertUtils.isNotNull(telephone, "telephone is null");
        AssertUtils.isNotNull(optCode, "optCode is null");
        String s = redis.get(RedisCache.USER_REDIS_TELEPHONE_OPT + ":" + telephone);
        if (!StringUtils.equals(s, optCode)){
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR,"短信验证码错误");
        }
    }

    public void saveUserInfo(UserModel userModel){
        AssertUtils.isNotNull(userModel, "userModel is null");
        ValidationResult result = validator.validate(userModel);
        if (result.isHasErrors()){
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR,result.getErrMsg());
        }
        //保存用户相关
        UserInfoDo userInfoDo = new UserInfoDo();
        BeanUtils.copyProperties(userModel, userInfoDo);
        try{
            userRepository.insertUser(userInfoDo);
        }catch (DuplicateKeyException e){
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "手机号已经重复");
        }
        //保存密码相关
        UserPasswordDo userPasswordDo = new UserPasswordDo();
        userPasswordDo.setEncrptPassword(userModel.getEncrptPassword());
        userPasswordDo.setUserId(userInfoDo.getId());
        userPasswordRepository.insertUserPassword(userPasswordDo);
    }

    public UserInfoDo login(String telephone, String password) {
        AssertUtils.isNotNull(telephone, "telephone is null");
        AssertUtils.isNotNull(password, "password is null");
        //验证用户是否存在
        UserInfoDo userInfoDo = userRepository.selectUserByTelePhone(telephone);
        if (userInfoDo == null) throw new BusinessException(EmBusinessError.USER_NOT_EXIST);
        //用户密码是否正确
        UserPasswordDo userPasswordDo = userPasswordRepository.selectUserPasswordByUserId(userInfoDo.getId());
        if (!StringUtils.equals(password, userPasswordDo.getEncrptPassword())){
            throw new BusinessException(EmBusinessError.USER_LOGIN_FAIL);
        }
        //缓存用户登陆信息到redis中UUID
        String uuid = UUID.randomUUID().toString().replace("-","");
        redis.set(RedisCache.USER_REDIS_SESSION + ":" + userInfoDo.getId(), uuid);
        redis.expire(uuid,1, TimeUnit.HOURS);
        userInfoDo.setUuid(uuid);
        return userInfoDo;
    }
}
